import sys
import time
import traceback
from datetime import datetime

# 添加必要的路径
sys.path.append('d:/git/liugejiao/vnpy')
sys.path.append('d:/git/liugejiao/vnpy_xt')

# 导入所需模块
from vnpy.event import EventEngine
from vnpy.trader.engine import MainEngine, LogEngine
from vnpy.trader.logger import INFO
from vnpy.trader.event import EVENT_ACCOUNT, EVENT_POSITION, EVENT_ORDER, EVENT_TRADE
from vnpy.trader.setting import SETTINGS
from vnpy_xt import XtGateway

# XT网关配置 - 使用中文参数格式
xt_setting = {
    "token": "",  # 客户端模式下token可以留空
    "股票市场": "是",
    "期货市场": "否",
    "期权市场": "否",
    "仿真交易": "是",  # 根据实际情况修改
    "账号类型": "股票",
    "QMT路径": r"D:/gjzqqmt_ceshi",  # 修改为实际的QMT安装路径
    "资金账号": "40743071"  # 修改为实际的资金账号
}

# 定义事件处理函数
def process_account_event(event):
    """处理账户事件"""
    try:
        account = event.data
        print(f"[{datetime.now()}] 账户更新: {account.accountid} 总资产: {account.balance}, 可用资金: {account.available}")
    except Exception as e:
        print(f"[{datetime.now()}] 处理账户事件错误: {e}")

def process_position_event(event):
    """处理持仓事件"""
    try:
        position = event.data
        print(f"[{datetime.now()}] 持仓更新: {position.vt_symbol} {position.direction.value} 持仓量: {position.volume}")
    except Exception as e:
        print(f"[{datetime.now()}] 处理持仓事件错误: {e}")

def process_order_event(event):
    """处理订单事件 - 显示详细订单信息"""
    try:
        order = event.data
        print(f"[{datetime.now()}] 订单更新: {order.vt_orderid}")
        print(f"  合约: {order.vt_symbol}")
        print(f"  方向: {order.direction.value}")
        print(f"  开平: {order.offset.value}")
        print(f"  价格: {order.price}")
        print(f"  数量: {order.volume}")
        print(f"  成交: {order.traded}")
        print(f"  状态: {order.status.value}")
        # 使用datetime属性代替time属性
        print(f"  时间: {order.datetime}")
    except Exception as e:
        print(f"[{datetime.now()}] 处理订单事件错误: {e}")

def process_trade_event(event):
    """处理成交事件 - 显示详细成交信息"""
    try:
        trade = event.data
        print(f"[{datetime.now()}] 成交回报: {trade.vt_tradeid}")
        print(f"  合约: {trade.vt_symbol}")
        print(f"  订单ID: {trade.vt_orderid}")
        print(f"  方向: {trade.direction.value}")
        print(f"  开平: {trade.offset.value}")
        print(f"  成交价格: {trade.price}")
        print(f"  成交数量: {trade.volume}")
        # 使用datetime属性代替time属性
        print(f"  成交时间: {trade.datetime}")
    except Exception as e:
        print(f"[{datetime.now()}] 处理成交事件错误: {e}")

def main():
    """最终版XT网关演示，确保只创建和启动一次EventEngine"""
    print(f"[{datetime.now()}] 最终版XT网关演示启动")
    
    # 只创建一次的核心组件
    event_engine = None
    main_engine = None
    
    try:
        # 配置日志
        SETTINGS["log.active"] = True
        SETTINGS["log.level"] = INFO
        SETTINGS["log.console"] = True
        SETTINGS["log.file"] = True
        
        # 关键步骤：只创建一次EventEngine
        print(f"[{datetime.now()}] 创建EventEngine...")
        event_engine = EventEngine()
        
        # 创建MainEngine - MainEngine会自动启动EventEngine
        print(f"[{datetime.now()}] 创建MainEngine...")
        main_engine = MainEngine(event_engine)
        
        # 在MainEngine创建后注册事件监听
        print(f"[{datetime.now()}] 注册事件监听器...")
        event_engine.register(EVENT_ACCOUNT, process_account_event)
        event_engine.register(EVENT_POSITION, process_position_event)
        event_engine.register(EVENT_ORDER, process_order_event)
        event_engine.register(EVENT_TRADE, process_trade_event)
        
        # 添加日志引擎
        print(f"[{datetime.now()}] 添加日志引擎...")
        log_engine = main_engine.add_engine(LogEngine)
        
        # 添加XT网关
        print(f"[{datetime.now()}] 添加XT网关...")
        main_engine.add_gateway(XtGateway)
        
        # 连接XT网关
        print(f"[{datetime.now()}] 连接XT网关...")
        main_engine.connect(xt_setting, "XT")
        
        # 等待连接建立
        print(f"[{datetime.now()}] 等待连接建立...")
        time.sleep(5)
        
        # 查询数据
        print(f"[{datetime.now()}] 开始查询数据...")
        for i in range(3):
            print(f"[{datetime.now()}] 第{i+1}次查询...")
            xt_gateway = main_engine.get_gateway("XT")
            if xt_gateway:
                try:
                    print(f"[{datetime.now()}] 查询账户数据...")
                    xt_gateway.query_account()
                    time.sleep(1)
                    print(f"[{datetime.now()}] 查询持仓数据...")
                    xt_gateway.query_position()
                    time.sleep(1)
                    print(f"[{datetime.now()}] 查询订单数据...")
                    xt_gateway.query_order()
                    time.sleep(1)
                    
                    # 检查网关订单字典
                    if hasattr(xt_gateway, 'orders'):
                        order_count = len(xt_gateway.orders)
                        print(f"[{datetime.now()}] 网关订单字典中的订单数量: {order_count}")
                        # 打印前3个订单的详细信息
                        if order_count > 0:
                            print(f"[{datetime.now()}] 订单详细信息:")
                            for i, (order_id, order) in enumerate(list(xt_gateway.orders.items())[:3]):
                                print(f"  订单{i+1}:")
                                print(f"    订单号: {order.vt_orderid}")
                                print(f"    合约: {order.vt_symbol}")
                                print(f"    状态: {order.status.value}")
                                print(f"    价格: {order.price}")
                                print(f"    数量: {order.volume}")
                                print(f"    成交: {order.traded}")
                    
                    # 显式调用query_trade方法
                    print(f"[{datetime.now()}] 查询成交数据...")
                    try:
                        # 直接调用query_trade方法
                        xt_gateway.query_trade()
                        time.sleep(1)
                        
                        # 检查网关交易字典
                        if hasattr(xt_gateway, 'trades'):
                            trade_count = len(xt_gateway.trades)
                            print(f"[{datetime.now()}] 网关交易字典中的成交数量: {trade_count}")
                            # 打印前3个成交的详细信息
                            if trade_count > 0:
                                print(f"[{datetime.now()}] 成交详细信息:")
                                for i, (trade_id, trade) in enumerate(list(xt_gateway.trades.items())[:3]):
                                    print(f"  成交{i+1}:")
                                    print(f"    成交号: {trade.vt_tradeid}")
                                    print(f"    订单号: {trade.vt_orderid}")
                                    print(f"    合约: {trade.vt_symbol}")
                                    print(f"    方向: {trade.direction.value}")
                                    print(f"    价格: {trade.price}")
                                    print(f"    数量: {trade.volume}")
                                    print(f"    时间: {trade.time}")
                        else:
                            print(f"[{datetime.now()}] 警告: xt_gateway没有trades属性")
                    except Exception as e:
                        print(f"[{datetime.now()}] 查询成交时出错: {e}")
                    
                    # 直接访问td_api进行调试
                    print(f"[{datetime.now()}] 直接访问td_api进行调试...")
                    try:
                        if hasattr(xt_gateway, 'td_api'):
                            td_api = xt_gateway.td_api
                            print(f"[{datetime.now()}] td_api存在，连接状态: {getattr(td_api, 'connected', False)}")
                            print(f"[{datetime.now()}] td_api账户: {getattr(td_api, 'xt_account', '未知')}")
                            
                            # 检查td_api是否有xt_client
                            if hasattr(td_api, 'xt_client'):
                                print(f"[{datetime.now()}] td_api.xt_client存在")
                                
                                # 尝试直接调用td_api的查询方法
                                try:
                                    print(f"[{datetime.now()}] 直接调用td_api.query_order()")
                                    td_api.query_order()
                                    time.sleep(1)
                                except Exception as e:
                                    print(f"[{datetime.now()}] 直接调用td_api.query_order()失败: {e}")
                                
                                try:
                                    print(f"[{datetime.now()}] 直接调用td_api.query_trade()")
                                    td_api.query_trade()
                                    time.sleep(1)
                                except Exception as e:
                                    print(f"[{datetime.now()}] 直接调用td_api.query_trade()失败: {e}")
                            else:
                                print(f"[{datetime.now()}] 警告: td_api没有xt_client属性")
                        else:
                            print(f"[{datetime.now()}] 警告: xt_gateway没有td_api属性")
                    except Exception as e:
                        print(f"[{datetime.now()}] 直接访问td_api时出错: {e}")
                        traceback.print_exc()
                except Exception as e:
                    print(f"[{datetime.now()}] 查询错误: {e}")
            time.sleep(3)
        
        print(f"[{datetime.now()}] 查询完成，程序结束")
        
        # 最终统计
        print(f"\n[{datetime.now()}] ==== 最终数据统计 ====")
        if xt_gateway:
            # 检查订单数据
            if hasattr(xt_gateway, 'orders'):
                order_count = len(xt_gateway.orders)
                print(f"[{datetime.now()}] 总订单数: {order_count}")
                # 如果有订单，打印详细信息
                if order_count > 0:
                    print(f"[{datetime.now()}] 订单详情:")
                    for order_id, order in list(xt_gateway.orders.items())[:5]:  # 打印前5个订单
                        print(f"  - {order.vt_orderid}: {order.vt_symbol} {order.status.value} {order.volume}/{order.traded} @ {order.price}")
            else:
                print(f"[{datetime.now()}] 警告: 未找到orders属性")
            
            # 检查成交数据
            if hasattr(xt_gateway, 'trades'):
                trade_count = len(xt_gateway.trades)
                print(f"[{datetime.now()}] 总成交数: {trade_count}")
                # 如果有成交，打印详细信息
                if trade_count > 0:
                    print(f"[{datetime.now()}] 成交详情:")
                    for trade_id, trade in list(xt_gateway.trades.items())[:5]:  # 打印前5个成交
                        print(f"  - {trade.vt_tradeid}: {trade.vt_symbol} {trade.volume} @ {trade.price}")
            else:
                print(f"[{datetime.now()}] 警告: 未找到trades属性")
        
        # 检查gateway是否正确初始化了查询任务
        if xt_gateway and hasattr(xt_gateway, 'init_query'):
            print(f"[{datetime.now()}] 尝试重新初始化查询任务...")
            try:
                # 保存原有的查询函数列表
                query_funcs = getattr(xt_gateway, 'query_functions', [])
                # 调用init_query
                xt_gateway.init_query()
                # 确保query_order和query_trade在查询列表中
                if hasattr(xt_gateway, 'query_functions'):
                    if xt_gateway.query_order not in xt_gateway.query_functions:
                        xt_gateway.query_functions.append(xt_gateway.query_order)
                    if hasattr(xt_gateway, 'query_trade') and xt_gateway.query_trade not in xt_gateway.query_functions:
                        xt_gateway.query_functions.append(xt_gateway.query_trade)
                    print(f"[{datetime.now()}] 查询函数列表: {[f.__name__ for f in xt_gateway.query_functions]}")
            except Exception as e:
                print(f"[{datetime.now()}] 重新初始化查询任务时出错: {e}")
        
    except Exception as e:
        print(f"[{datetime.now()}] 发生错误: {e}")
        traceback.print_exc()
    finally:
        # 安全关闭资源
        print(f"[{datetime.now()}] 清理资源...")
        try:
            if event_engine and hasattr(event_engine, 'stop'):
                event_engine.stop()
                print(f"[{datetime.now()}] EventEngine已停止")
            if main_engine and hasattr(main_engine, 'close'):
                main_engine.close()
                print(f"[{datetime.now()}] MainEngine已关闭")
        except Exception as e:
            print(f"[{datetime.now()}] 关闭资源时发生错误: {e}")
        
        print(f"[{datetime.now()}] 程序已退出")

if __name__ == "__main__":
    # 直接运行，避免多进程带来的复杂性
    # 确保整个程序生命周期中只创建和启动一次EventEngine
    main()